﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using Core;
using System.ComponentModel;
using ERP.BusinessEntities.Base;
using ERP.BusinessEntities.Factory;
using System.Data;
using ERP.BusinessEntities;
using ERP.DAL;
using Core.Component;

namespace Components
{
    public enum LookUpStyle
    {
        Dropdown = 0,
        OnForm = 1
    }

    [System.ComponentModel.DefaultBindingProperty("ID")]
    public class SGVTextBoxLookUp:SGVTextBox, INotifyPropertyChanged
    {
        private const int EM_SETMARGINS = 0x00D3;
        private const int EC_LEFTMARGIN = 0x0001;
        private const int EC_RIGHTMARGIN = 0x0002;
        private const int EC_USEFONTINFO = 0xffff;


        public SGVButton LookUpButton;
        public SGVButton DrillButton;

        bool _allowLookUp = true;

        public bool AllowLookUp
        {
            get { return _allowLookUp; }
            set { _allowLookUp = value; }
        }
        bool _allowDrill = true;

        public bool AllowDrill
        {
            get { return _allowDrill; }
            set { _allowDrill = value; }
        }

        public LookUpStyle LookUpStl = LookUpStyle.OnForm;

        public bool isTextChanged = true;
        public bool isPendingLookup = false;
        public BaseBusinessController Ctrl;

        public Control ParentScreen
        {
            get { return this.FindForm(); }
        }

        public event EventHandler LookUpClick { add { LookUpButton.Click += value; } remove { LookUpButton.Click -= value; } }
        public event EventHandler DrillClick { add { DrillButton.Click += value; } remove { DrillButton.Click -= value; } }
        public event PropertyChangedEventHandler PropertyChanged;
        
        public SGVTextBoxLookUp()
            : base()
        {
            MinTypedCharacters = 1;
            #region LookUp Button
            LookUpButton = new SGVButton();
            LookUpButton.SizeChanged += (o, e) => OnResize(e);
            LookUpButton.FlatStyle = FlatStyle.Flat;
            LookUpButton.FlatAppearance.BorderSize = 0;
            LookUpButton.BackColor = Color.Transparent;
            LookUpButton.MouseMove += new MouseEventHandler(Button_MouseMove);
            LookUpButton.MouseLeave += new EventHandler(Button_MouseLeave);
            LookUpButton.KeyDown += new KeyEventHandler(Control_KeyDown);
            LookUpButton.TabStop = false;
            LookUpButton.VisibleChanged += new EventHandler(Button_VisibleChanged);
           
            Controls.Add(LookUpButton);
            #endregion

            #region Drill Button
            DrillButton = new SGVButton();
            DrillButton.SizeChanged += (o, e) => OnResize(e);
            DrillButton.FlatStyle = FlatStyle.Flat;
            DrillButton.FlatAppearance.BorderSize = 0;
            DrillButton.BackColor = Color.Transparent;
            DrillButton.Cursor = Cursors.Default;
            DrillButton.MouseMove += new MouseEventHandler(Button_MouseMove);
            DrillButton.MouseLeave += new EventHandler(Button_MouseLeave);
            DrillButton.TabStop = false;
            DrillButton.VisibleChanged += new EventHandler(Button_VisibleChanged);
            Controls.Add(DrillButton);

            #endregion


            SetButtonProperties();

            SetMargin();

            LookUpClick += new EventHandler(LookUp_Click);
            DrillClick += new EventHandler(SGVTextBoxLookUp_DrillClick);

            this.KeyDown += new KeyEventHandler(Control_KeyDown);

            this.TextChanged += new EventHandler(this_TextChanged);

            this.GotFocus += new EventHandler(Control_GotFocus);
            this.LostFocus += new EventHandler(Control_LostFocus);
        }

        void SGVTextBoxLookUp_DrillClick(object sender, EventArgs e)
        {
            if (String.IsNullOrEmpty(DataSourceTable)) return;

            BSModuleMapingsInfo maping = AppContext.ModuleMapingCtrl.GetModuleMapingByTable(DataSourceTable);
            if (maping == null) return;

            AppContext.OpenModule(maping.ModuleName + "Module", ID, Core.Base.ActionType.None, true);
        }

        int _iD;
        public int ID
        {
            set
            {
                _iD = value;
                OnIDChanged();
                if (_iD <= 0)
                    DrillButton.Visible = false;
                else
                    DrillButton.Visible = true;

                isTextChanged = false;
                this.Text = String.Empty;
                if (Ctrl != null)
                {
                    Object obj = Ctrl.GetObjectById(_iD);
                    if (obj != null && String.IsNullOrEmpty(DataSourceDisplayColumn) == false)
                    {
                        Object objDisplay = AppContext.GetProperty(obj, DataSourceDisplayColumn);
                        if (objDisplay != null)
                            this.Text = Convert.ToString(objDisplay);
                        else
                            this.Text = String.Empty;
                    }
                }
                isTextChanged = true;
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs("ID"));
            }
            get
            {
                return _iD;
            }
        }

        public virtual void OnIDChanged()
        {
        }

        [CategoryAttribute(".SGV"), DescriptionAttribute("minimum characters to be typed before suggestions are displayed")]
        public int MinTypedCharacters
        {
            get;
            set;
        }

        #region Event
        public virtual void Control_KeyDown(object sender, KeyEventArgs e)
        {
            if ((e.KeyCode == Keys.Escape))
            {
                if (isPopupShow == true)
                    HideSuggestionListBox();
                else
                    this.ID = 0;
                // work is done
                e.Handled = true;
            }
            else if (e.KeyCode == Keys.F2)
            {
                LookUp_Click(LookUpButton, new EventArgs());
            }
            //if (e.KeyCode == Keys.Enter)
            //{
            //    // select the item in the ListBox
            //    SelectItemText();
            //    e.Handled = true;
            //}
        }
        public virtual void this_TextChanged(object sender, EventArgs e)
        {
            
        }
        #endregion

        //protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        //{
        //    if (keyData == (Keys.Control | Keys.A))
        //    {
        //        this.SelectAll();
        //    }
        //    else if (keyData == (Keys.Control | Keys.C))
        //    {
        //        this.Copy();
        //    }
        //    else if (keyData == (Keys.Control | Keys.V))
        //    {
        //        this.Paste();
        //    }
        //    else if (keyData == (Keys.Control | Keys.X))
        //    {
        //        this.Cut();
        //    }
        //    else if (keyData == (Keys.Control | Keys.Z))
        //    {
        //        this.Undo();
        //    }
        //    else if (keyData == Keys.Enter)
        //    {
        //        SelectItemText();
        //    }

        //    return base.ProcessCmdKey(ref msg, keyData);
        //}

        public virtual void SelectItemText()
        {
            if (String.IsNullOrEmpty(this.Text) || this.Text.Trim().Length == 0)
            {
                ID = 0;
            }
            else
            {
                DataTable dt = GetSearchDataSet(this.Text.Trim());
                if (dt == null || dt.Rows.Count == 0)
                {
                    ID = 0;
                }
                else if (dt.Rows.Count == 1)
                {
                    ID = Convert.ToInt32(dt.Rows[0][AppContext.cstID]);
                    HideSuggestionListBox();
                }
                else
                {
                    ShowSuggetionBox();
                }
            }
        }

        public bool isPopupShow = false;
        public virtual void ShowSuggetionBox()
        {
            int iSelectedID = AppContext.ShowSearchScreen(module, DataSourceTable, null, DataSourceColumns, this.Text.Trim());;

            if (iSelectedID > 0)
                ID = iSelectedID;
        }

        public virtual void HideSuggestionListBox()
        {
        }

        public virtual void RefreshDropdownLit(String text)
        {

        }

        public DataTable GetSearchDataSet(String text)
        {
            if (this.DesignMode == true) return null;
            if (Ctrl == null) return null;

            String strColumns = DataSourceColumns.Replace('|', ',');
            String[] strColumnWheres = DataSourceColumns.Split('|');

            StringBuilder strWhereBuilder = new StringBuilder();
            if (strColumnWheres.Length > 0)
                strWhereBuilder.Append(String.Format(@" {0} like N'%{1}%'", strColumnWheres[0], text));

            for (int i = 1; i < strColumnWheres.Length; i++)
            {
                strWhereBuilder.Append(String.Format(@" OR {0} like N'%{1}%'", strColumnWheres[i], text));
            }

            String strQuery = String.Format(@"SELECT {0}, {1} FROM {2} 
                                        WHERE AAStatus = 'Alive'
                                        AND ({3})", AppContext.cstID, strColumns, DataSourceTable, strWhereBuilder.ToString());

            DataSet ds = Ctrl.GetDataset(strQuery);

            if (ds != null && ds.Tables.Count > 0)
                return ds.Tables[0];

            return null;
        }

        void Button_MouseLeave(object sender, EventArgs e)
        {
            ((Button)sender).BackColor = this.BackColor;
            //((Button)sender).BackColor = Color.Transparent;
            //((Button)sender).FlatStyle = FlatStyle.Flat;
            //((Button)sender).FlatAppearance.BorderSize = 0;
        }

        void Button_MouseMove(object sender, MouseEventArgs e)
        {
            ((Button)sender).BackColor = this.BackColor;
            //((Button)sender).BackColor = Color.Tomato;
            //((Button)sender).FlatStyle = FlatStyle.Standard;
            //BrowseButton.BackColor = Color.Transparent;
            //((Button)sender).FlatAppearance.BorderSize = 1;
        }
        void Button_VisibleChanged(object sender, EventArgs e)
        {
            ((Button)sender).BackColor = this.BackColor;
        }

        public void SetButtonProperties()
        {
            LookUpButton.Size = new Size(20, ClientSize.Height-2);
            LookUpButton.Location = new Point(ClientSize.Width - LookUpButton.Width - 1, 1);

            DrillButton.Size = new Size(20, ClientSize.Height - 2);
            DrillButton.Location = new Point(1, 1);
        }

        public void SetMargin()
        {
            SendMessage(this.Handle, EM_SETMARGINS, (IntPtr)EC_LEFTMARGIN, (IntPtr)20);
            SendMessage(this.Handle, EM_SETMARGINS, (IntPtr)2, (IntPtr)(LookUpButton.Width << 16));
        }

        protected override void OnCreateControl()
        {
            base.OnCreateControl();
            
        }

        void DrillButton_VisibleChanged(object sender, EventArgs e)
        {
            Button btn = (Button)sender;
            if (btn.Visible == true)
            {
                SendMessage(this.Handle, EM_SETMARGINS, (IntPtr)EC_LEFTMARGIN, (IntPtr)btn.Width);
                SendMessage(this.Handle, EM_SETMARGINS, (IntPtr)EC_RIGHTMARGIN, (IntPtr)btn.Width);
            }
            else
                SendMessage(this.Handle, EM_SETMARGINS, (IntPtr)EC_LEFTMARGIN, (IntPtr)0);
        }

        void BrowseButton_VisibleChanged(object sender, EventArgs e)
        {
            Button btn = (Button)sender;
            if (btn.Visible == true)
                SendMessage(this.Handle, EM_SETMARGINS, (IntPtr)EC_RIGHTMARGIN, (IntPtr)btn.Width);
            else
                SendMessage(this.Handle, EM_SETMARGINS, (IntPtr)EC_RIGHTMARGIN, (IntPtr)0);
        }

        public override void Control_GotFocus(object sender, EventArgs e)
        {
            base.Control_GotFocus(sender, e);
           
        }

        public override void Control_LostFocus(object sender, EventArgs e)
        {
            base.Control_LostFocus(sender, e);
            //if (isPendingLookup == false && ID <= 0)
            //{
            //    isPendingLookup = true;
            //    SelectItemText();
            //    isPendingLookup = false;
            //}
        }

        public override void SetFocusAppreance()
        {
            base.SetFocusAppreance();
            LookUpButton.BackColor = this.BackColor;
            DrillButton.BackColor = this.BackColor;
        }

        public override void SetLostFocusAppreance()
        {
            base.SetLostFocusAppreance();
            LookUpButton.BackColor = this.BackColor;
            DrillButton.BackColor = this.BackColor;
        }


        //void Control_LostFocus(object sender, EventArgs e)
        //{
        //    SGVControlHelper.ControlLostFocus(this);
        //}

        //void Control_GotFocus(object sender, EventArgs e)
        //{
        //    SGVControlHelper.ControlFocus(this);
        //}

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            SetButtonProperties();
            SetMargin();
        }

        public override void Init()
        {
            base.Init();
            Ctrl = Host.GetCtrl(DataSourceTable);
            //Ctrl = (BaseBusinessController)BusinessFactory.CreateBusinessCtrl(DataSourceTable + "Controller");

            LookUpButton.Image = AppUtil.GetImageFromFileName(Application.StartupPath + @"/Images", "Look", 10, 10);
            LookUpButton.ImageAlign = ContentAlignment.MiddleCenter;

            DrillButton.Image = AppUtil.GetImageFromFileName(Application.StartupPath + @"/Images", "Drill", 10, 10); ;
            DrillButton.ImageAlign = ContentAlignment.MiddleCenter;

            //LookUpButton.BackgroundImage = AppUtil.GetImageFromFileName("Look", 10, 10);
            //LookUpButton.BackgroundImageLayout = ImageLayout.Center;

            //DrillButton.BackgroundImage = AppUtil.GetImageFromFileName("Drill", 10, 10);
            //DrillButton.BackgroundImageLayout = ImageLayout.Center;
        }

        public virtual void LookUp_Click(object sender, EventArgs e)
        {
            if (isPopupShow == false)
            {
                ShowSuggetionBox();
                RefreshDropdownLit(this.Text.Trim());
            }
            else
                HideSuggestionListBox();
        }

        [System.Runtime.InteropServices.DllImport("user32.dll")]
        private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
    }
}
